// This file was added for increasing performance in video encoding/decoding
#include "BufferedByteStream.h"
#include <stdio.h>
#include <string.h>

BufferedByteStream::BufferedByteStream(): bufferpos(0)
{
}

BufferedByteStream::~BufferedByteStream()
{
}

void BufferedByteStream::WriteRaw(const void *data, unsigned int size)
{
	unsigned char *bytedata = (unsigned char*)data;
	unsigned int bufferleft = BUFFERSIZE - bufferpos;
	unsigned int bufferfillnew = size;

	if (bufferfillnew > bufferleft)
		bufferfillnew = bufferleft;

	memcpy(buffer+bufferpos, bytedata, bufferfillnew);
	bufferpos += bufferfillnew;

	if (bufferpos >= BUFFERSIZE)
	{
		ByteStream::Write(buffer, BUFFERSIZE);
		bufferpos = 0;
	}

	unsigned int bufferleftover = size - bufferfillnew;

	if (bufferleftover >= BUFFERSIZE)
	{
		ByteStream::Write(bytedata+bufferfillnew, bufferleftover);
		bufferpos = 0;
	}
	else if (bufferleftover > 0)
	{
		memcpy(buffer, bytedata+bufferfillnew, bufferleftover);
		bufferpos = bufferleftover;
	}
}

void BufferedByteStream::Write(const void *data, unsigned int size)
{
	BufferedByteStream::WriteRaw(data, size);
}

unsigned int BufferedByteStream::Read(void *data, unsigned int size)
{
	return BufferedByteStream::ReadRaw(data, size);
}


unsigned int BufferedByteStream::ReadRaw(void *data, unsigned int size)
{
	unsigned char *bytedata = (unsigned char*)data;
	unsigned int totalread = ByteStream::Read(data, size);
	unsigned int leftover = size - totalread;

	if (leftover && bufferpos)
	{
		unsigned int readsize = leftover;

		if (readsize > bufferpos)
			readsize = bufferpos;

		unsigned int leftoverbuffer = bufferpos - readsize;

		memcpy(bytedata+totalread, buffer, readsize);
		memmove(buffer, buffer+readsize, leftoverbuffer);
		bufferpos = leftoverbuffer;
	}

	return totalread;
}

void BufferedByteStream::Clear()
{
	bufferpos = 0;

	ByteStream::Clear();
}

void BufferedByteStream::WriteToFile(const char *filename)
{
	Flush();

	ByteStream::WriteToFile(filename);
}

void BufferedByteStream::Flush()
{
	if (bufferpos)
	{
		ByteStream::Write(buffer, bufferpos);

		bufferpos = 0;
	}
}